## This test checks how we handle the --elf-cg-profile option.

# RUN: yaml2obj %s -o %t.o
# RUN: llvm-readobj %t.o --cg-profile | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf %t.o --cg-profile | FileCheck %s --check-prefix=GNU
# RUN: llvm-readobj %t.o --elf-cg-profile | FileCheck %s --check-prefix=LLVM
# RUN: llvm-readelf %t.o --elf-cg-profile | FileCheck %s --check-prefix=GNU

# LLVM:      CGProfile [
# LLVM-NEXT:  CGProfileEntry {
# LLVM-NEXT:    From: foo (1)
# LLVM-NEXT:    To: bar (2)
# LLVM-NEXT:    Weight: 89
# LLVM-NEXT:  }
# LLVM-NEXT:  CGProfileEntry {
# LLVM-NEXT:    From: bar (2)
# LLVM-NEXT:    To: foo (1)
# LLVM-NEXT:    Weight: 98
# LLVM-NEXT:  }
# LLVM-NEXT: ]

# GNU: GNUStyle::printCGProfile not implemented

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
  Machine: EM_X86_64
Sections:
  - Name: .llvm.call-graph-profile
    Type: SHT_LLVM_CALL_GRAPH_PROFILE
    Entries:
      - Weight: 89
      - Weight: 98
    EntSize: [[ENTSIZE=<none>]]
  - Name: .rel.llvm.call-graph-profile
    Type: SHT_REL
    Info: .llvm.call-graph-profile
    Relocations:
      - Symbol: foo
        Type:   R_X86_64_NONE
      - Offset: 0x0
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: foo
        Type:   R_X86_64_NONE
Symbols:
  - Name: foo
  - Name: bar

## Check we report a warning when unable to get the content of the SHT_LLVM_CALL_GRAPH_PROFILE section.
# RUN: yaml2obj %s -DENTSIZE=0xF -o %t2.o
# RUN: llvm-readobj %t2.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=LLVM-ERR
# RUN: llvm-readelf %t2.o --cg-profile | FileCheck %s --check-prefix=GNU

# LLVM-ERR: warning: '[[FILE]]': unable to load the SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 1] has invalid sh_entsize: expected 8, but got 15

## Check we report a warning when unable to dump a name of a symbol.
# RUN: yaml2obj %s --docnum=2 -o %t3.o
# RUN: llvm-readobj %t3.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=LLVM-BROKEN-SYM
# RUN: llvm-readelf %t3.o --cg-profile | FileCheck %s --check-prefix=GNU

# LLVM-BROKEN-SYM:      CGProfile [
# LLVM-BROKEN-SYM-NEXT:   CGProfileEntry {
# LLVM-BROKEN-SYM-NEXT:     From: A (1)
# LLVM-BROKEN-SYM-NEXT: warning: '[[FILE]]': unable to read the name of symbol with index 2: st_name (0xff) is past the end of the string table of size 0x5
# LLVM-BROKEN-SYM-NEXT:     To: <?> (2)
# LLVM-BROKEN-SYM-NEXT:     Weight: 10
# LLVM-BROKEN-SYM-NEXT:   }
# LLVM-BROKEN-SYM-NEXT:   CGProfileEntry {
# LLVM-BROKEN-SYM-NEXT:     From: <?> (2)
# LLVM-BROKEN-SYM-NEXT:     To: B (3)
# LLVM-BROKEN-SYM-NEXT:     Weight: 20
# LLVM-BROKEN-SYM-NEXT:   }
# LLVM-BROKEN-SYM-NEXT:   CGProfileEntry {
# LLVM-BROKEN-SYM-NEXT:     From: (0)
# LLVM-BROKEN-SYM-NEXT: warning: '[[FILE]]': unable to read the name of symbol with index 4: unable to get symbol from section [index 4]: invalid symbol index (4)
# LLVM-BROKEN-SYM-NEXT:     To: <?> (4)
# LLVM-BROKEN-SYM-NEXT:     Weight: 20
# LLVM-BROKEN-SYM-NEXT:   }
# LLVM-BROKEN-SYM-NEXT: ]

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
  Machine: EM_X86_64
Sections:
  - Name: .llvm.call-graph-profile
    Type: SHT_LLVM_CALL_GRAPH_PROFILE
    Entries:
      - Weight: 10
      - Weight: 20
      - Weight: 20
  - Name: .rel.llvm.call-graph-profile
    Type: SHT_REL
    Info: .llvm.call-graph-profile
    Relocations:
      - Symbol: 1
        Type:   R_X86_64_NONE
      - Offset: 0x0
        Symbol: 2
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: 2
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: 3
        Type:   R_X86_64_NONE
      - Offset: 0x10
        Symbol: 0x0 ## Null symbol.
        Type:   R_X86_64_NONE
      - Offset: 0x10
        Symbol: 0x4 ## This index goes past the end of the symbol table.
        Type:   R_X86_64_NONE
  - Name:    .strtab
    Type:    SHT_STRTAB
    Content: "0041004200" ## '\0', 'A', '\0', 'B', '\0'
Symbols:
  - StName: 1    ## 'A'
  - StName: 0xFF ## An arbitrary currupted index in the string table.
  - StName: 3    ## 'B'

## Check we report a warning when a relocation section is not present.
# RUN: yaml2obj %s --docnum=3 -o %t4.o
# RUN: llvm-readobj %t4.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t4.o --check-prefix=LLVM-NO-RELOC
# RUN: llvm-readobj %t4.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t4.o --check-prefix=LLVM-NO-RELOC

# LLVM-NO-RELOC:      warning: '[[FILE]]': relocation section for a call graph section doesn't exist
# LLVM-NO-RELOC-NEXT: CGProfile [
# LLVM-NO-RELOC-NEXT:  CGProfileEntry {
# LLVM-NO-RELOC-NEXT:    Weight: 89
# LLVM-NO-RELOC-NEXT:  }
# LLVM-NO-RELOC-NEXT:  CGProfileEntry {
# LLVM-NO-RELOC-NEXT:    Weight: 98
# LLVM-NO-RELOC-NEXT:  }
# LLVM-NO-RELOC-NEXT: ]

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name: .llvm.call-graph-profile
    Type: SHT_LLVM_CALL_GRAPH_PROFILE
    Entries:
      - Weight: 89
      - Weight: 98
Symbols:
  - Name: foo
  - Name: bar

## Check we report a warning when the number of relocation section entries does not match the number of call graph entries.
# RUN: yaml2obj %s --docnum=4 -o %t5.o
# RUN: llvm-readobj %t5.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t5.o --check-prefix=LLVM-RELOC-GRAPH-NOT-MATCH
# RUN: llvm-readobj %t5.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t5.o --check-prefix=LLVM-RELOC-GRAPH-NOT-MATCH

# LLVM-RELOC-GRAPH-NOT-MATCH:      warning: '[[FILE]]': number of from/to pairs does not match number of frequencies
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: CGProfile [
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT:  CGProfileEntry {
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT:    Weight: 89
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT:  }
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT:  CGProfileEntry {
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT:    Weight: 98
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT:  }
# LLVM-RELOC-GRAPH-NOT-MATCH-NEXT: ]

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
  Machine: EM_X86_64
Sections:
  - Name: .llvm.call-graph-profile
    Type: SHT_LLVM_CALL_GRAPH_PROFILE
    Entries:
      - Weight: 89
      - Weight: 98
  - Name: .rel.llvm.call-graph-profile
    Type: SHT_REL
    Info: .llvm.call-graph-profile
    Relocations:
      - Symbol: foo
        Type:   R_X86_64_NONE
      - Offset: 0x0
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: foo
        Type:   R_X86_64_NONE
      - Offset: 0x10
        Symbol: foo
        Type:   R_X86_64_NONE
Symbols:
  - Name: foo
  - Name: bar

## Check we report a warning when a REL relocation section can't be loaded.
# RUN: yaml2obj %s --docnum=5 -o %t6.o
# RUN: llvm-readobj %t6.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t6.o --check-prefix=LLVM-RELOC-WRONG-SIZE
# RUN: llvm-readobj %t6.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t6.o --check-prefix=LLVM-RELOC-WRONG-SIZE

# LLVM-RELOC-WRONG-SIZE:      warning: '[[FILE]]': unable to load relocations for SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 2] has invalid sh_entsize: expected 16, but got 24
# LLVM-RELOC-WRONG-SIZE-NEXT: CGProfile [
# LLVM-RELOC-WRONG-SIZE-NEXT:  CGProfileEntry {
# LLVM-RELOC-WRONG-SIZE-NEXT:    Weight: 89
# LLVM-RELOC-WRONG-SIZE-NEXT:  }
# LLVM-RELOC-WRONG-SIZE-NEXT:  CGProfileEntry {
# LLVM-RELOC-WRONG-SIZE-NEXT:    Weight: 98
# LLVM-RELOC-WRONG-SIZE-NEXT:  }
# LLVM-RELOC-WRONG-SIZE-NEXT: ]

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
  Machine: EM_X86_64
Sections:
  - Name: .llvm.call-graph-profile
    Type: SHT_LLVM_CALL_GRAPH_PROFILE
    Entries:
      - Weight: 89
      - Weight: 98
  - Name: .rel.llvm.call-graph-profile
    Type: SHT_REL
    Info: .llvm.call-graph-profile
    Relocations:
      - Symbol: foo
        Type:   R_X86_64_NONE
      - Offset: 0x0
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: foo
        Type:   R_X86_64_NONE
    EntSize: 24
Symbols:
  - Name: foo
  - Name: bar

## GNU strip may convert SHT_REL to SHT_RELA. Test we can handle SHT_RELA.
# RUN: yaml2obj %s --docnum=6 -o %t7.o
# RUN: llvm-readobj %t7.o --cg-profile | FileCheck %s --check-prefix=LLVM-RELA
# RUN: llvm-readelf %t7.o --cg-profile | FileCheck %s --check-prefix=GNU-RELA

# LLVM-RELA:      CGProfile [
# LLVM-RELA-NEXT:  CGProfileEntry {
# LLVM-RELA-NEXT:    From: foo (1)
# LLVM-RELA-NEXT:    To: bar (2)
# LLVM-RELA-NEXT:    Weight: 89
# LLVM-RELA-NEXT:  }
# LLVM-RELA-NEXT:  CGProfileEntry {
# LLVM-RELA-NEXT:    From: bar (2)
# LLVM-RELA-NEXT:    To: foo (1)
# LLVM-RELA-NEXT:    Weight: 98
# LLVM-RELA-NEXT:  }
# LLVM-RELA-NEXT: ]

# GNU-RELA: GNUStyle::printCGProfile not implemented

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
  Machine: EM_X86_64
Sections:
  - Name: .llvm.call-graph-profile
    Type: SHT_LLVM_CALL_GRAPH_PROFILE
    Entries:
      - Weight: 89
      - Weight: 98
  - Name: .rela.llvm.call-graph-profile
    Type: SHT_RELA
    Info: .llvm.call-graph-profile
    Relocations:
      - Symbol: foo
        Type:   R_X86_64_NONE
      - Offset: 0x0
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: foo
        Type:   R_X86_64_NONE
Symbols:
  - Name: foo
  - Name: bar

## Check we report a warning when a RELA relocation section can't be loaded.
# RUN: yaml2obj %s --docnum=7 -o %t8.o
# RUN: llvm-readobj %t8.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t8.o --check-prefix=LLVM-RELOC-WRONG-SIZE-RELA
# RUN: llvm-readobj %t8.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t8.o --check-prefix=LLVM-RELOC-WRONG-SIZE-RELA

# LLVM-RELOC-WRONG-SIZE-RELA:      warning: '[[FILE]]': unable to load relocations for SHT_LLVM_CALL_GRAPH_PROFILE section: section [index 2] has invalid sh_entsize: expected 24, but got 16
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT: CGProfile [
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT:  CGProfileEntry {
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT:    Weight: 89
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT:  }
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT:  CGProfileEntry {
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT:    Weight: 98
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT:  }
# LLVM-RELOC-WRONG-SIZE-RELA-NEXT: ]

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
  Machine: EM_X86_64
Sections:
  - Name: .llvm.call-graph-profile
    Type: SHT_LLVM_CALL_GRAPH_PROFILE
    Entries:
      - Weight: 89
      - Weight: 98
  - Name: .rela.llvm.call-graph-profile
    Type: SHT_RELA
    Info: .llvm.call-graph-profile
    Relocations:
      - Symbol: foo
        Type:   R_X86_64_NONE
      - Offset: 0x0
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: bar
        Type:   R_X86_64_NONE
      - Offset: 0x8
        Symbol: foo
        Type:   R_X86_64_NONE
    EntSize: 16
Symbols:
  - Name: foo
  - Name: bar

## Check that we report a warning when we fail to get a section associated with
## a relocation section.

# RUN: yaml2obj %s --docnum=8 -o %t9.o
# RUN: llvm-readobj %t9.o --cg-profile 2>&1 | FileCheck %s -DFILE=%t9.o --check-prefix=LLVM-RELOC-NO-SECTIONS
# RUN: llvm-readobj %t9.o --elf-cg-profile 2>&1 | FileCheck %s -DFILE=%t9.o --check-prefix=LLVM-RELOC-NO-SECTIONS

# LLVM-RELOC-NO-SECTIONS: warning: '[[FILE]]': unable to get CG Profile section(s): SHT_RELA section with index 1: failed to get a relocated section: invalid section index: 255

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
  Machine: EM_X86_64
Sections:
  - Name: .rela.llvm.call-graph-profile
    Type: SHT_RELA
    Info: 0xFF
